#include "stepmotor.h"
STEPMOTOR_TypeDef stepmotor ={1600,0,0,0};

void Stepmotor_Init(void)
{
	//打开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	
	//gpio口配置
	//PB5
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; 
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;                    //
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);     
	
	//PB6
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;                    //
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	//tim定时器配置 
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct = {0};
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; 
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 2000 - 1;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);
	
	//tim定时器通道配置
	TIM_OCInitTypeDef TIM_OCInitStruct = {0};
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0; 
	TIM_OC1Init(TIM4,&TIM_OCInitStruct);
	
	//使能重装载寄存器（影子寄存器）
	TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM4,ENABLE);
	
	//设置占空比
	TIM_SetCompare1(TIM4,1000);
	
	//设置步进电机的转动速度
	StepMotor_SetSpeed(50);
	
	//关闭定时器
	TIM_Cmd(TIM4,DISABLE);
	
	//定时器的中断使能
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
	NVIC_EnableIRQ(TIM4_IRQn);
}

/*************************************************
* 函数名     :StepMotor_Move
* 函数功能   :步进电机旋转到指定角度函数
* 函数参数   :float angle  指定角度
* 函数返回值 :void
* 函数说明   :
*							
**************************************************/
void StepMotor_Move(float angle)
{
	stepmotor.targetangel = angle;      //更新目标值
	float difvalue = stepmotor.angle - stepmotor.targetangel;
	if(difvalue < -stepmotor.pulseangle || difvalue > stepmotor.pulseangle)
	{   
		if(angle > 0 && difvalue < 0)
		{
			STEPDIR(DIR_RIGHT);
		}
		if(angle >= 0 && difvalue > 0)
		{
			STEPDIR(DIR_LEFT);
		}
		if(angle <= 0 && difvalue < 0)
		{
			STEPDIR(DIR_RIGHT);
		}
		if(angle < 0 && difvalue > 0)
		{
			STEPDIR(DIR_LEFT);
		}
		TIM_Cmd(TIM4,ENABLE);
	}
	else
	{
		TIM_Cmd(TIM4,DISABLE);
	}
}

/*************************************************
* 函数名     :StepMotor_SetSpeed
* 函数功能   :设置步进电机旋转速度函数
* 函数参数   :float angle  旋转速度（°/s）
* 函数返回值 :void
* 函数说明   :				
**************************************************/
void StepMotor_SetSpeed(float angle)
{
	stepmotor.pulseangle = 360.0 / stepmotor.subdiv;
	stepmotor.speed = angle;
	
	//根据速度求每秒钟得脉冲数 = 每秒钟的角度 / 单脉冲角度
	float pulsenum = angle / stepmotor.pulseangle + 0.5;
	if(pulsenum < 0.16)
	{
		//如果每秒钟脉冲数小于0.16个，则设置速度为每秒0.16个脉冲
		TIM4->PSC = 7200 - 1;
		TIM_SetAutoreload(TIM4,65535);
		TIM_SetCompare1(TIM4,32768);
	}
	else if(pulsenum < 16)
	{
		//如果脉冲给的速度比65.546ms慢，那么我们可以重新修改分频值
		TIM4->PSC = 7200 - 1;
		TIM_SetAutoreload(TIM4,10000.0f/pulsenum);
		TIM_SetCompare1(TIM4,10000.0f/pulsenum/2);
	}
	else
	{
		//在1us一次的计数速率下，1s内的脉冲个数最快1us一次，最慢65.536ms一次
		TIM4->PSC = 72 - 1;
		TIM_SetAutoreload(TIM4,1000000.0f/pulsenum);
		TIM_SetCompare1(TIM4,1000000.0f/pulsenum/2);
	}
}


/*************************************************
* 函数名     :TIM4_IRQHandler
* 函数功能   :定时器4中断服务函数
* 函数参数   :void
* 函数返回值 :void
* 函数说明   :执行步进电机的旋转和停止				
**************************************************/
void TIM4_IRQHandler(void)
{
	TIM_ClearFlag(TIM4,TIM_FLAG_Update);
	if(STEPDIRGET)
	{
		stepmotor.angle += stepmotor.pulseangle;
	}
	else
	{
		stepmotor.angle -= stepmotor.pulseangle; 
	}
	//检测当前角度与目标角度差值，误差在一个±步角度之间则表示角度一致，关闭定时器
	float difvalue = stepmotor.angle - stepmotor.targetangel;
	if(difvalue < -stepmotor.pulseangle || difvalue > stepmotor.pulseangle)
	{
		TIM_Cmd(TIM4,ENABLE);
	}
	else
	{
		TIM_Cmd(TIM4,DISABLE);
	}
	
}

